class ReservationsController < ApplicationController

  require_role 'member', :for => [:new, :confirm, :check_payment]
  require_role 'admin', :for => [:edit, :update, :destroy], :unless => '@current_member.authorized_for_reservation?(params[:id])'

  before_filter :login_required

  def show
    @reservation = Reservation.find(params[:id], :include => :member)
  end
  
  def index
    @reservations = Reservation.find(:all, :conditions => ['reservations.start_date > ? AND reservations.end_date < ? AND reservations.state = ?', Time.now..advance(:weeks => 3).beginning_of_week, Time.now.advance(:weeks => 3).beginning_of_week, 'paid'], :include => [:post, :member])
  end

  def destroy
    @reservation = Reservation.find(params[:id])
    if @reservation.start_date > Time.now
      if @reservation.paid?
        @member = Member.find(session[:member_id])
        @member.credit += @reservation.credit_needed
        @member.save
      end
      if @reservation.destroy
        flash[:success] = 'Reservation cancelled'
        redirect_to member_path(@member)
      end
    else
      flash[:error] = 'Unable to delete reservation'
      redirect_to reservation_path(@reservation)
    end
  end

  def edit
    @reservation = Reservation.find(params[:id])
    redirect_to reservation_path(@reservation) unless @reservation.end_date > Time.now
  end

  def update
    @reservation = Reservation.find(params[:id])
    if @reservation.end_date > Time.now
      @category = @reservation.post.category

      @reservation.set_dates_and_hours(params["reservation"], params[:start_hour], params[:end_hour])

      @start_date = @reservation.start_date
      @end_date = @reservation.end_date

      @avalaible_posts = @category.find_avalaible_posts(@start_date, @end_date)

      if @avalaible_posts and @avalaible_posts.size > 0
        @reservation.post_id = @avalaible_posts.first.id
        #substract 1 minute (60 seconds) to the submitted hour so that people leave the desk 1 minute earlier
        @reservation.end_date -= 60
        if @reservation.save
          flash[:success] = 'Reservation updated'
          render :action => 'show'
        else
          render :action => 'edit'
        end
      else
        flash[:error] = 'New dates unsuitable'
        render :action => 'edit'
      end
    end
  end


  def new
    @category = Category.find(params[:category_id])
    @reservation = Reservation.new(params[:reservation])
    if request.post?

      @reservation.member_id = session[:member_id]

      #compute start_date and end_date for reservation as those were submitted by a customized javascript calendar
      @reservation.set_dates_and_hours(params["reservation"], params[:start_hour], params[:end_hour])

      @start_date = @reservation.start_date
      @end_date = @reservation.end_date

      @avalaible_posts = @category.find_avalaible_posts(@start_date, @end_date)

      if @avalaible_posts and @avalaible_posts.size > 0
        @reservation.post_id = @avalaible_posts.first.id
        #substract 1 minute (60 seconds) to the submitted hour so that people leave the desk 1 minute earlier
        @reservation.end_date -= 60
        if @reservation.save
          render :action => 'find'
        end
      else
        i = 0
        while (@avalaible_posts.size == 0 and i < 30)
          i += 1
          @start_date = increment_by_30min(@start_date)
          @end_date = increment_by_30min(@end_date)
          @avalaible_posts = @category.find_avalaible_posts(@start_date, @end_date)
        end
        if @avalaible_posts and @avalaible_posts.size > 0
          flash[:notice] = 'We are booked for the time and date you asked for. We do however have space available for ' + @start_date.strftime('%a, %d %b %Y %H:%M')
          @reservation.start_date = @start_date
          @reservation.end_date = @end_date - 60
          @reservation.post_id = @avalaible_posts.first.id
          if @reservation.save
            @alternative = true
          end
          render :action => 'find'
        else
          flash[:error] = 'No solution found for given dates'
          render :action => 'new'
        end
      end
    else
      @reservation.start_date = Time.now
    end
  end

  def increment_by_30min(date)
    # 1800 is to increment existing date by 30 minutes
    date = date + 1800
    if date.hour >= 18
      # station c closes at 6pm so when time reaches 6, advance to 9am
      date = date + 54000
    end
    date
  end

  def confirm
    @reservation = Reservation.find(params[:id])
    if @reservation.member_id == session[:member_id]
      @reservation.confirm!
    end
    @member = Member.find(session[:member_id])
    if @member.membership == 'flex' 
      if @member.credit < @reservation.credit_needed
        redirect_to :action => 'send_to_paypal', :id => @reservation.id
      else
        redirect_to :action => 'confirm_debit', :id => @reservation.id
      end
    elsif (@member.membership == 'resident')
      @reservation.credited!
      redirect_to reservation_path(@reservation)
    end
  end

  def send_to_paypal
    @reservation = Reservation.find(params[:id])
    @member = Member.find(session[:member_id])
  end

  def confirm_debit
    @reservation = Reservation.find(params[:id])
    if request.post?
      @reservation.credited!
      @member = Member.find(session[:member_id])
      @member.credit -= @reservation.credit_needed
      @member.save
      flash[:success] = "#{@reservation.credit_needed} units were debited from your account. You have #{@member.credit} left"
      redirect_to reservation_path(@reservation)
    end
  end

  #ununsed action -- for the moment -- till we integrate paypal
  def notify_ipn
    if params[:payment_status] == 'Completed'
      @reservation = Reservation.find(params[:invoice])
      old_status_code =  @order.order_status_code_id 
      @reservation.credited!
    end
    redirect_to :action => 'thanks'
  end
end
